package com.nexgo.payment.pack;

import com.nexgo.common.ByteUtils;
import com.nexgo.common.TlvUtils;
import com.nexgo.data.entity.SendData;
import com.nexgo.data.entity.SendDataBuilder;
import com.nexgo.payment.constrant.PreferencesConstants;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.databases.TransRecord;
import com.nexgo.payment.entity.TransData;
import com.nexgo.payment.util.EmvUtils;
import com.nexgo.payment.util.MessageHelper;
import com.nexgo.payment.util.StringUtils;

import java8.util.Optional;

/**
 * 批上送IC卡通知类交易
 * <p>
 * Created by xiaox on 2017/9/6.
 */
class BatchUploadIccNotifyBuilder extends DataBuilder {
    private TransRecord mTransRecord;
    private TransType mOrgTransType;

    BatchUploadIccNotifyBuilder(TransData transData, DataSource repository) {
        super(transData, repository);
        mTransRecord = mRepository.queryTransRecord(mTransData.getOrgTraceNum());
        mOrgTransType = TransType.values()[mTransRecord.getTransType()];
    }

    @Override
    SendData form() {
        SendData sendData = new SendDataBuilder().setListener(mListener).setSignListener(mSignListener).createSendData();
        sendData.setHeader(MessageHelper.formMessageHeader(mRepository.getParamValue(PreferencesConstants.TPDU)));
        sendData.setMsgType(mTransData.getTransType().getMsgType());
        sendData.setPan(mTransRecord.getPan());
        sendData.setProcCode(mOrgTransType.getProcCode());
        sendData.setAmount(StringUtils.leftPad(mTransRecord.getAmount(), 12, '0'));
        sendData.setTraceNum(mTransRecord.getTraceNum());
        sendData.setExpDate(mTransRecord.getExpDate());
        String entryMode = mTransRecord.getEntryMode();
        sendData.setEntryMode(new StringBuilder(entryMode).replace(entryMode.length() - 1, entryMode.length(), "2").toString());
        sendData.setCsn(mTransRecord.getCsn());
        sendData.setConditionCode(mOrgTransType.getConditionCode());
        sendData.setRefNum(mTransRecord.getOrgRefNum());
        sendData.setAuthCode(StringUtils.rightPad(mTransData.getOrgAuthCode(), 6, ' '));
        sendData.setTerminalId(mTransRecord.getTerminalId());
        sendData.setMerchantId(mTransRecord.getMerchantId());
        sendData.setFundType(mTransRecord.getFundType());
        sendData.setField60(formField60());
        sendData.setField61(formField61());
        sendData.setField63(formField63());
        return sendData;
    }


    private String formField60() {
        StringBuilder sb = new StringBuilder();
        sb.append(StringUtils.firstNonEmpty(mOrgTransType.getFuncCode(), "00"));
        sb.append(StringUtils.firstNonEmpty(mTransRecord.getBatchNum(), mRepository.getParamValue(PreferencesConstants.BATCH_NUMBER)));
        sb.append("000");
        sb.append("6");
        sb.append(mTransRecord.getIsFallback() ? "2" : "0");
        return ByteUtils.byteArray2HexString(sb.toString().getBytes());
    }

    private String formField61() {
        StringBuilder sb = new StringBuilder();
        sb.append(StringUtils.firstNonEmpty(mTransRecord.getOrgBatchNum(), "000000"));
        sb.append(StringUtils.firstNonEmpty(mTransRecord.getOrgTraceNum(), "000000"));
        sb.append(StringUtils.firstNonEmpty(mTransRecord.getOrgDate(), "0000"));
        return sb.toString();
    }

    private String formField63() {
        return Optional.ofNullable(mTransRecord.getResultTlv())
                .map(s -> TlvUtils.decodingTLV(s, "9f06"))
                .filter(strings -> strings.size() != 0)
                .map(strings -> strings.get(0))
                .map(s -> EmvUtils.getInterCodeByAid(s))
                .orElse("000");
    }
}
